/**
 * @file rect.cpp
 * @author ThomasKingFree (dulu150@126.com)
 * @brief
 * @version 0.1
 * @date 2021-03-21
 *
 * @copyright Copyright (c) 2021
 *
 */

#include "utils/rect.h"

namespace YueGUI {
Rect::Rect(int16_t x, int16_t y, int16_t width, int16_t height) {
    originX_ = x;
    originY_ = y;
    width_ = width;
    height_ = height;
}

Rect::Rect(const Rect &other)
{
    originX_ = other.originX_;
    originY_ = other.originY_;
    width_ = other.width_;
    height_ = other.height_;
}

Rect::Rect(const Rect &&other)
{
    originX_ = other.originX_;
    originY_ = other.originY_;
    width_ = other.width_;
    height_ = other.height_;
}

Rect::~Rect()
{
    originX_ = -1;
    originY_ = -1;
    width_ = 0;
    height_ = 0;
}

void Rect::operator = (const Rect &other)
{
    originX_ = other.originX_;
    originY_ = other.originY_;
    width_ = other.width_;
    height_ = other.height_;
}

void Rect::operator = (const Rect &&other)
{
    originX_ = other.originX_;
    originY_ = other.originY_;
    width_ = other.width_;
    height_ = other.height_;
}

void Rect::Join(const Rect &other)
{
    originX_ = (originX_ < other.originX_) ? originX_ : other.originX_;
    originY_ = (originY_ < other.originY_) ? originY_ : other.originY_;

    int16_t rightX = originX_ + width_ - 1;
    int16_t otherRightX = other.originX_ + other.width_ - 1;
	width_ = (rightX > otherRightX) ? width_ : (otherRightX - originX_ + 1);

    int16_t bottomY_ = originY_ + height_ - 1;
    int16_t otherBottomY = other.originY_ + other.height_ - 1;
	height_ = (bottomY_ > otherBottomY) ? height_ : (otherBottomY - originY_ + 1);
}

bool Rect::Intersect(const Rect &other)
{
    if (other.originX_ > (originX_ + width_ - 1)) {
        return false;
    } else if (originX_ > (other.originX_ + other.width_ - 1)) {
        return false;
    } else if (other.originY_ > (originY_ + height_ - 1)) {
        return false;
    } else if (originY_ > (other.originY_ + other.height_ - 1)) {
        return false;
    } else {
        originX_ = originX_ > other.originX_ ? originX_ : other.originX_;
        originY_ = originY_ > other.originY_ ? originY_ : other.originY_;
        int16_t rightX = originX_ + width_ - 1;
        int16_t otherRightX = other.originX_ + other.width_ - 1;
        width_ = (rightX > otherRightX) ? (otherRightX - originX_ + 1) : (rightX - originX_ + 1);
        int16_t bottomY = originY_ + height_ - 1;
        int16_t otherBottomY = other.originY_ + other.height_ - 1;
        height_ = (bottomY > otherBottomY) ? (otherBottomY - originY_ + 1) : (bottomY - originY_ + 1);
        return true;
    }
}

bool Rect::Contain(const Rect &other)
{
    if ((other.originX_ >= originX_) &&
        (other.originY_ >= originY_) &&
        ((other.originX_ + other.width_) <= (originX_ + width_)) &&
        ((other.originY_ + other.height_) <= (originY_ + height_))) {
        return true;
    } else {
        return false;
    }
}
} // namespace YuiGUI
